package com.chandra.pos.product.web;

import com.chandra.pos.SearchCriteria;
import com.chandra.pos.product.dao.entity.Product;
import com.chandra.pos.product.dao.entity.UnitType;
import com.chandra.pos.product.exception.ProductNotFoundException;
import com.chandra.pos.product.service.IProductService;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortMeta;
import org.primefaces.model.SortOrder;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * Created with IntelliJ IDEA.
 * Customer: T4671
 * Date: 10/5/13
 * Time: 10:23 AM
 * To change this template use File | Settings | File Templates.
 */
@Named("productMB")
public class ProductManagedBean extends LazyDataModel<Product> implements Serializable {

    @Inject
    IProductService productService;

    private static final String SUCCESS = "success";
    private static final String ERROR = "error";


    private Long id;
    private Boolean hideSaleDialog=false;
    private  String name;

    private  String description;

    private Integer unitType;

    private BigDecimal salePrice;

    private BigDecimal  costPrice;

    private BigDecimal reorderQuantity;

    private BigDecimal quantity;

    private List<Product> filteredResults;

    public BigDecimal getQuantity() {
        return quantity;
    }

    public void setQuantity(BigDecimal quantity) {
        this.quantity = quantity;
    }

    public BigDecimal getReorderQuantity() {
        return reorderQuantity;
    }

    public UnitType[] getUnitTypes(){

        return UnitType.values();
    }

    public void setReorderQuantity(BigDecimal reorderQuantity) {
        this.reorderQuantity = reorderQuantity;
    }

    public BigDecimal getSalePrice() {
        return salePrice;
    }

    public void setSalePrice(BigDecimal salePrice) {
        this.salePrice = salePrice;
    }

    public BigDecimal getCostPrice() {
        return costPrice;
    }

    public void setCostPrice(BigDecimal costPrice) {
        this.costPrice = costPrice;
    }

    public Integer getUnitType() {
        return unitType;
    }

    public void setUnitType(Integer unitType) {
        this.unitType = unitType;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Boolean getHideSaleDialog() {
        return hideSaleDialog;
    }

    public void setHideSaleDialog(Boolean hideSaleDialog) {
        this.hideSaleDialog = hideSaleDialog;
    }

    private Product selectedProduct;

    public LazyDataModel<Product> getLazyModel() {
        return this;
    }

    /**
     * Reset Fields
     */
    public void reset() {
        this.setId(0l);
        this.setName("");
        this.setSalePrice(null);
        this.setDescription("");
        this.setQuantity(null);


    }

    public List<Product> complete(String query) {
        List<String> results = new ArrayList<String>();

        PageRequest pageRequest=new PageRequest(0,5) ;

        List<Product> page= productService.searchProducts(query+"%");


        return page;
    }

    public void addProduct(ActionEvent actionEvent) {
        RequestContext context = RequestContext.getCurrentInstance();
        FacesMessage msg = null;
        boolean loggedIn = false;

        try {
            try {
                productService.getProduct(getName());
                msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Product already exist.", "Product already exist.");
            } catch (ProductNotFoundException e) {

                Product product = new Product();
                // product.setId(getId());
                Random random=new Random();
                product.setId(random.nextLong());
                product.setUnit(UnitType.Bag);
                product.setStockQuantity(getQuantity());
                product.setReorderQuantity(getReorderQuantity());
                product.setName(getName());
                product.setDescription(getDescription());
                product.setSalePrice(getSalePrice());
                productService.addProduct(product);
                loggedIn=true;
                 msg = new FacesMessage("Product "+getName()+" created succesfully.");
                reset();

            }



        } catch (DataAccessException e1) {
            loggedIn = false;
            msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Account Error", e1.getMessage());
        }
        FacesContext.getCurrentInstance().addMessage(null, msg);
        context.addCallbackParam("loggedIn", loggedIn);


    }

    public void handleSelect(SelectEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Selected:" + event.getObject().toString(), null);
        this.selectedProduct = (Product) event.getObject();
        hideSaleDialog=true;
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public void addSelectedItem() {

        this.hideSaleDialog=false;

    }

    public void cancelSelectedItem() {

        this.hideSaleDialog=false;

    }
    public void removeSelectedItem() {

        this.hideSaleDialog=false;

    }

    public Product getSelectedProduct() {
        return selectedProduct;
    }

    public void setSelectedProduct(Product selectedProduct) {
        this.selectedProduct = selectedProduct;
    }

    @Override
    public List<Product> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {


        SearchCriteria searchCriteria=new SearchCriteria();

        searchCriteria.setPageSize(pageSize);
        searchCriteria.setFirst(first);
        searchCriteria.setSortField(sortField);
        searchCriteria.setSortOrder(sortOrder);

        if(filters !=null && filters.size() ==1 && filters.containsKey("globalFilter"))
         searchCriteria.setQuery(filters.get("globalFilter"));


        List<Product> data = productService.search(searchCriteria);


        int dataSize = data.size();
        this.setRowCount(dataSize);

        return data;
    }

    public void setFilteredResults(List<Product> filteredResults) {
        this.filteredResults = filteredResults;
    }

    public List<Product>  getFilteredResults(){

        return filteredResults;
    }


    public List<Product> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String,String> filters) {

        // PageRequest pageRequest=new PageRequest(first,pageSize, new Sort(Sort.Direction.ASC, sortField)) ;
        PageRequest pageRequest=new PageRequest(first,pageSize) ;


        Page data = productService.getProducts(pageRequest);


        int dataSize = data.getSize();
        this.setRowCount(dataSize);

        return data.getContent();
    }
    @Override
    public Long getRowKey(Product product) {
        return product.getId();
    }

    @Override
    public Product getRowData(String rowKey) {
        Product user = productService.getProductById(Long.valueOf(rowKey));

        return user;

    }
    public void onRowSelect(SelectEvent event){
        FacesMessage msg = new FacesMessage("Customer Selected", ((Product) event.getObject()).getName());
        FacesContext.getCurrentInstance().addMessage(null, msg);
        this.selectedProduct=(Product)event.getObject();

    }

    public void handleSalePriceUpdate(){

        System.out.println("handleSalePriceUpdate");
        FacesMessage msg = new FacesMessage("Sales Price Updated");
        FacesContext.getCurrentInstance().addMessage(null, msg);

    }
}
